

/* Scheduler includes. */
#include "FreeRTOS.h"
#include "task.h"

/* Application includes */
#include "./uart/uart.h"
#include "./monitor/monitor.h"

/* Constants required for hardware setup. */
#define mainALL_BITS_OUTPUT		( ( unsigned portCHAR ) 0xff )
#define mainMAX_FREQUENCY		( ( unsigned portCHAR ) 121 )

/* Appplication task priorities. */
#define mainMONITOR_TASK_PRIORITY		( tskIDLE_PRIORITY + 1 )
#define mainUART_TASK_PRIORITY			( tskIDLE_PRIORITY + 2 )

//Perform the hardware setup required by the MSP-FET430U80 
static void prvSetupHardware( void );

/*****Supervising variables for tracking RTOS stability******/
xTaskHandle xuartTaskHandle;
xTaskHandle xmonitorTaskHandle;
//hold how many times the idle task was called
volatile unsigned portLONG ulIdleLoops = 0UL;
//holds how much memory is availabe, used to optimize heap size
//you should change the configTOTAL_HEAP_SIZE in FreeRTOSConfig.h accordingly
volatile size_t xheapSize = 0UL;
volatile portBASE_TYPE xuartTaskWaterMark = 0UL; //stores available stack
volatile portBASE_TYPE xmonitorTaskWaterMark = 0UL; //stores available stack
/***End supervising variables (see in watch debug windown)***/

int main( void ){
  prvSetupHardware();
  
  /* Create one task. Note that a real application should check
  the return value of the xTaskCreate() call to ensure the task was created
  successfully. */
  xTaskCreate( vUartTask, /* Pointer to the function that implements the task. */
              "Uart Task",/* Text name for the task. Debugging only. */
              100, /* Stack depth */
              NULL, /* We are not using the task parameter. */
              mainUART_TASK_PRIORITY, /* Task priority */
              &xuartTaskHandle ); /* handle to our task */
  xTaskCreate( vMonitorTask, "Monitor Task", 100, NULL, mainMONITOR_TASK_PRIORITY, 
              &xmonitorTaskHandle ); /* handle to our task */
  
  /* Start the scheduler. */
  vTaskStartScheduler();
  
  /* If all is well then main() will never reach here as the scheduler will
  now be running the tasks. If main() does reach here then it is likely that
  there was insufficient heap memory available for the idle task to be created.
  CHAPTER 5 provides more information on memory management. */
  for( ;; );
}
/*-----------------------------------------------------------*/

static void prvSetupHardware( void )
{
	/* Stop the watchdog. */
	WDTCTL = WDTPW + WDTHOLD;

	/* Setup DCO+ for ( xtal * D * (N + 1) ) operation. */
	FLL_CTL0 |= DCOPLUS + XCAP18PF;

	/* X2 DCO frequency, 8MHz nominal DCO */
	SCFI0 |= FN_4;

	/* (121+1) x 32768 x 2 = 7.99 Mhz */
	SCFQCTL = mainMAX_FREQUENCY;
        
        /* Used for the onboard LED. */
	P5DIR |= 0x02;
        /*Used to trigger a external reset on the TS-7300 board*/
        P4DIR |= 0x01;
        P5OUT &= 0xFD; //turn off LED
        P4OUT |= 0x01; //turn off reset        
}
/*-----------------------------------------------------------*/

//function that is automatically called by the idle task once per iteration
//of the idle task loop
/* Idle hook functions MUST be called vApplicationIdleHook(), take no parameters,
and return void. */
void vApplicationIdleHook( void ){
    //Measuring the amount of spare processing capacity
    volatile portLONG lValue;
	
	for( ;; ){
		ulIdleLoops++;		
        xheapSize = xPortGetFreeHeapSize();
        xuartTaskWaterMark = uxTaskGetStackHighWaterMark(xuartTaskHandle);
        xmonitorTaskWaterMark = uxTaskGetStackHighWaterMark(xmonitorTaskHandle);
		/* Place the processor into low power mode. */
        //it doesnt work very good with serial communciation
        //uart doesnt wake up on time
        //LPM3; 
        //_BIC_SR_IRQ(LPM3_bits);
	}
}


